package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private SetmealService setmealService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void saveWithFlavor(DishDto dishDto) {
        this.save(dishDto);
        Long dishId = dishDto.getId();
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dishId);
        }
        dishFlavorService.saveBatch(flavors);
    }

    @Override
    public DishDto getByIdWithFlavor(Long id) {
        //查询菜品基本信息,从dish表中查询
        Dish dish = this.getById(id);

        DishDto dishDto=new DishDto();

        BeanUtils.copyProperties(dish,dishDto);

        //查询当前菜品对应的口味信息,从dish_flavor查询
        LambdaQueryWrapper<DishFlavor> lbqw=new LambdaQueryWrapper<>();
        lbqw.eq(DishFlavor::getDishId,dish.getId());
        List<DishFlavor> list = dishFlavorService.list(lbqw);
        dishDto.setFlavors(list);
        return dishDto;
    }

    @Override
    @Transactional
    public void updateWithFlavor(DishDto dishDto) {
        //更新dish菜品表的基本信息
        this.updateById(dishDto);
        //清理当前菜品对应口味数据---dish_flavor表的delete操作
     LambdaQueryWrapper<DishFlavor> lqw=new LambdaQueryWrapper();

     lqw.eq(DishFlavor::getDishId,dishDto.getId());

     dishFlavorService.remove(lqw);

        //添加当前提交过来的口味数据---dish_flavor表的insert操作
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dishDto.getId());
        }
        dishFlavorService.saveBatch(flavors);
    }

    //对菜品批量或者是单个进行停售或者是启售
    @Override
    public void updateBatchStatus(Integer status, List<Long> ids) {
        LambdaQueryWrapper<Dish> queryWrapper=new LambdaQueryWrapper<>();
        //in(字段名称,集合)
        queryWrapper.in(ids!=null,Dish::getId,ids);
        List<Dish> list = this.list(queryWrapper);

        for (Dish dish : list) {
            if (dish!=null){
                dish.setStatus(status);
                this.updateById(dish);
            }

        }
    }

    //菜品批量删除/单个删除
    @Override
    public boolean deleteDish(List<Long> ids) {
        //1.根据菜品id在Stemeal_dish表中查出哪些套餐包含菜品
        LambdaQueryWrapper<SetmealDish> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.in(SetmealDish::getDishId,ids);
        List<SetmealDish> setmealDishList = setmealDishService.list(queryWrapper);
        if (setmealDishList.size()==0){
            //在 deleteByIds()方法中已经做了起售菜品不能删除的判断
            this.deleteByIds(ids);
            //相应的口味表dish_flavor中菜品的口味数据也要删除
            LambdaQueryWrapper<DishFlavor> queryWrapper1=new LambdaQueryWrapper<>();
            queryWrapper1.in(DishFlavor::getDishId,ids);
            dishFlavorService.remove(queryWrapper1);
            return true;
        }
        //如果菜品有关联套餐，并且该套餐正在售卖，那么不能删除
        //得到与删除菜品关联的套餐id
        ArrayList<Long> Setmeal_idList=new ArrayList<>();
        for (SetmealDish setmealDish : setmealDishList) {
            Long setmealId = setmealDish.getSetmealId();
            Setmeal_idList.add(setmealId);
        }
        //查询出与删除菜品相关联的套餐
        LambdaQueryWrapper<Setmeal> queryWrapper2=new LambdaQueryWrapper<>();
        queryWrapper2.in(Setmeal::getId,Setmeal_idList);
        List<Setmeal> setmealList = setmealService.list(queryWrapper2);
        for (Setmeal setmeal : setmealList) {
            Integer status = setmeal.getStatus();
            if (status==1){
                return false;
            }
        }
        //要删除的菜品关联的套餐没有在售，可以删除
        //这下面的代码并不一定会执行,因为如果前面的for循环中出现status == 1,那么下面的代码就不会再执行
        this.deleteByIds(ids);
        LambdaQueryWrapper<DishFlavor> queryWrapper3 = new LambdaQueryWrapper<>();
        queryWrapper3.in(DishFlavor::getDishId, ids);
        dishFlavorService.remove(queryWrapper3);
        return true;

    }

    /**
     * 套餐批量删除和单个删除
     * @param ids
     */
    @Override
    @Transactional
    public void deleteByIds(List<Long> ids) {
        //构造条件查询器
        LambdaQueryWrapper<Dish> queryWrapper=new LambdaQueryWrapper<>();
        //查询该商品是否在售卖,如果是则抛出业务异常
        queryWrapper.in(ids!=null,Dish::getId,ids);
        List<Dish> list = this.list(queryWrapper);
        for (Dish dish : list) {
            Integer status = dish.getStatus();
            //状态为0不是在售卖可以删除
            if (status==0){
                this.removeById(dish.getId());
            }else {
                //此时应该回滚,因为前面删除了,但是后面仍然在售卖
                throw new CustomException("删除菜品中有正在售卖的菜品,无法全部删除");
            }
        }

    }
}
